package com.lin.cloud.disk.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.lin.cloud.disk.common.entity.request.AccountRequestDTO;
import com.lin.cloud.disk.common.enums.EDeleteStatus;
import com.lin.cloud.disk.common.enums.EFileType;
import com.lin.cloud.disk.common.enums.EUploadStatus;
import com.lin.cloud.disk.entity.dto.DirectoryAndFileDTO;
import com.lin.cloud.disk.entity.dto.LogicDeleteStatusDTO;
import com.lin.cloud.disk.entity.pojo.File;
import com.lin.cloud.disk.entity.request.CountTotalSizeRequest;
import com.lin.cloud.disk.entity.request.file.*;
import com.lin.cloud.disk.entity.response.*;
import com.lin.cloud.disk.mapper.FileMapper;
import com.lin.cloud.disk.service.IFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

/** 文件服务实现类
 * @author ljc
 * @date 2021/2/3 16:46
 */
@Service
@Slf4j
public class FileServiceImpl implements IFileService {

    @Resource
    private FileMapper fileMapper;


    /**
     * 获取用户文件列表
     *
     * @param request
     * @return
     */
    @Override
    public List<File> getFileList(GetUserFileRequest request){
        List<File> fileList = fileMapper.getFileList(request);
        if (CollectionUtils.isNotEmpty(fileList)){
            return fileList;
        }else{
            return Collections.EMPTY_LIST;
        }
    }

    /**
     * 通过Id更新文件
     * @param file
     */
    @Override
    public void updateById(File file){
        fileMapper.updateById(file);
    }

    /**
     * 创建文件
     * @param file
     */
    @Override
    public void createFile(File file){
        fileMapper.insert(file);
    }


    /**
     * 获取正在上传的文件
     * @param request
     * @return
     */
    @Override
    public List<GetBeingUploadFileResponse> getBeingUploadFile(GetBeingUploadFileRequest request){

        GetUserFileRequest getUserFileRequest = new GetUserFileRequest();
        getUserFileRequest.setUserId(request.getUserDTO().getId());
        getUserFileRequest.setIsDelete(EDeleteStatus.UN_DELETE.getStatus());
        getUserFileRequest.setUploadStatus(EUploadStatus.UN_DONE_UPLOAD.getStatus());
        List<File> fileList = fileMapper.getFileList(getUserFileRequest);
        if (CollectionUtils.isEmpty(fileList)){
            return Collections.EMPTY_LIST;
        }
        List<GetBeingUploadFileResponse> beingUploadList = new ArrayList<>(fileList.size());
        GetBeingUploadFileResponse beingUploadFile = null;
        for (File file: fileList){
            BeanUtil.copyProperties(file,beingUploadFile);
            beingUploadList.add(beingUploadFile);
        }
        return beingUploadList;
    }

    /**
     * 通过文件类型获取文件列表
     * @param request
     * @return
     */
    @Override
    public List<DirectoryAndFileDTO> getFileListByFileType(GetFileListByFileTypeRequest request){
        // 计算文件类型
        List<String> fileSuffixList = EFileType.getFileSuffixList(request.getFileType());
        GetUserFileRequest getUserFileRequest = new GetUserFileRequest();
        getUserFileRequest.setUserId(request.getUserDTO().getId());
        getUserFileRequest.setIsDelete(EDeleteStatus.UN_DELETE.getStatus());
        getUserFileRequest.setUploadStatus(EUploadStatus.DONE_UPLOAD.getStatus());
        // 类型列表不为空则数值 类型为空默认为其他
        if (CollectionUtils.isNotEmpty(fileSuffixList)){
            getUserFileRequest.setFileSuffixList(fileSuffixList);
        }
        // 查询数据
        List<File> fileList = fileMapper.getFileList(getUserFileRequest);
        if (CollectionUtils.isEmpty(fileList)){
            return Collections.EMPTY_LIST;
        }
        // 类型转换
        DirectoryAndFileDTO directoryAndFileDTO = null;
        List<DirectoryAndFileDTO> responseList = new ArrayList<>(fileList.size());
        for (File file : fileList) {
            directoryAndFileDTO = new DirectoryAndFileDTO();
            BeanUtil.copyProperties(file,directoryAndFileDTO);
            directoryAndFileDTO.setIsDir(false);
            responseList.add(directoryAndFileDTO);
        }
        return responseList;
    }

    /**
     * 逻辑删除恢复
     * @param deleteStatusDTO
     * @return
     */
    @Override
    public Integer logicDeleteOrRecover(LogicDeleteStatusDTO deleteStatusDTO){
        return fileMapper.logicDeleteOrRecover(deleteStatusDTO);
    }

    /**
     * 通过文件ID删除文件
     * @param fileId
     * @return
     */
    @Override
    public Integer removeFileById(Long fileId){
        return fileMapper.deleteById(fileId);
    }

    /**
     * 统计总文件大小
     * @param request
     * @return
     */
    @Override
    public String countTotalFileSize(CountTotalSizeRequest request){
        BigInteger totalFileSize = fileMapper.countTotalFileSize(request);
        if (null == totalFileSize){
            return "0";
        }
        totalFileSize = totalFileSize.divide(new BigInteger("1048576"));;
        return totalFileSize.toString();
    }



    /**
     * 获取文件资源分片
     * @param request
     * @return
     */
    @Override
    public List<GetFileResourceZoneResponse> getFileResourceZone(AccountRequestDTO request){
        GetUserFileRequest getUserFileRequest = new GetUserFileRequest();
        getUserFileRequest.setIsDelete(EDeleteStatus.UN_DELETE.getStatus());
        getUserFileRequest.setUploadStatus(EUploadStatus.DONE_UPLOAD.getStatus());
        getUserFileRequest.setUserId(request.getUserDTO().getId());
        List<File> fileResourceZoneList = fileMapper.getFileResourceZoneList(getUserFileRequest);

        List<GetFileResourceZoneResponse> responseList = new ArrayList<>();
        // 存在分片 根据后缀分类
        if (CollectionUtil.isNotEmpty(fileResourceZoneList)){

            Map<Integer,List<File>> fileTypeAndListMap = new HashMap<>();
            Map<String, List<File>> fileSuffixMap = fileResourceZoneList.stream().collect(Collectors.groupingBy(File::getFileSuffix));
            // 遍历map 计算分类
            for (Map.Entry<String,List<File>>  entry: fileSuffixMap.entrySet()){
                String fileSuffix = entry.getKey();
                // 计算后缀类型
                Integer fileTypeBySuffix = EFileType.getFileTypeBySuffix(fileSuffix);

                // 加入到Map中
                if (fileTypeAndListMap.containsKey(fileTypeBySuffix)){
                    List<File> fileList = fileTypeAndListMap.get(fileTypeBySuffix);
                    fileList.addAll(entry.getValue());
                    fileTypeAndListMap.put(fileTypeBySuffix,fileList);
                }else {
                    fileTypeAndListMap.put(fileTypeBySuffix,entry.getValue());
                }
            }
            // 统计类型
            GetFileResourceZoneResponse response = null;
            for (Map.Entry<Integer,List<File>> fileTypeList: fileTypeAndListMap.entrySet()){
                Integer fileType= fileTypeList.getKey();
                response = new GetFileResourceZoneResponse();
                response.setFileType(fileType);
                response.setTypeDesc(EFileType.getFileDescByType(fileType));
                Long totalSize = fileTypeList.getValue().stream().map(File::getFileSize).count();
                response.setTotalSize(totalSize);
                responseList.add(response);
            }
        }
        return responseList;
    }

    @Override
    public int updateFileName(File file) {
        file.setUpdateTime(new Date());
        return fileMapper.updateById(file);
    }

    /**
     * 批量移动文件
     * @param request
     */
    @Override
    public void batchMoveFile(BatchMoveFileRequest request){
        fileMapper.batchMoveFile(request);
    }

    /**
     * 搜索文件
     * @param request
     * @return
     */
    @Override
    public List<DirectoryAndFileDTO> searchFile(SearchFileRequest request){
        GetUserFileRequest getUserFileRequest = new GetUserFileRequest();
        getUserFileRequest.setIsDelete(EDeleteStatus.UN_DELETE.getStatus());
        getUserFileRequest.setUploadStatus(EUploadStatus.DONE_UPLOAD.getStatus());
        getUserFileRequest.setUserId(request.getUserDTO().getId());
        getUserFileRequest.setFileName(request.getFileName());
        List<File> fileList = fileMapper.getFileList(getUserFileRequest);
        List<DirectoryAndFileDTO> directoryAndFileDTOList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(fileList)){
            fileList.forEach(file -> {
                DirectoryAndFileDTO directoryAndFileDTO = new DirectoryAndFileDTO();
                BeanUtil.copyProperties(file, directoryAndFileDTO);
                directoryAndFileDTO.setIsDir(false);
                directoryAndFileDTOList.add(directoryAndFileDTO);
            });
            // 整体通过createTime排序
            directoryAndFileDTOList.sort(Comparator.comparing(DirectoryAndFileDTO::getCreateTime).reversed());
        }
        return directoryAndFileDTOList;
    }
}
